package vsy.buzzwordbingo.login;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;

import vsy.buzzwordbingo.model.GameCore;
import vsy.buzzwordbingo.model.Player;

public class PlayerAuthenticationProvider implements AuthenticationProvider {

	private String playerRole;

	@Resource
	private GameCore gameCore;

	@Override
	public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		Assert.notNull(playerRole, "A Player role must be provided.");

		Player player = gameCore.getPlayer(authentication.getName());
		if (player == null) {
			throw new UsernameNotFoundException("Can't find player " + authentication.getName());
		}
		if (!player.matchesPassword((String)authentication.getCredentials())) {
			throw new BadCredentialsException("Wrong password.");
		}

//		try {
//			
//			player = gameCore.loginPlayer(authentication.getName(),
//					(String) authentication.getCredentials());
//		} catch (DuplicatePlayerException e) {
//			throw new LockedException("Player name already taken: "
//					+ authentication.getName(), e);
//		}

		return createSuccessfullAuthentication(authentication, player);
	}

	private Authentication createSuccessfullAuthentication(
			Authentication authentication, Player player) {
		Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
		authorities.addAll(authentication.getAuthorities());
		authorities.add(new GrantedAuthorityImpl(playerRole));

		UsernamePasswordAuthenticationToken successfullAuthentication = new UsernamePasswordAuthenticationToken(
				authentication.getPrincipal(), authentication.getCredentials(),
				authorities);
		successfullAuthentication.setDetails(player);
		return successfullAuthentication;
	}

	@Override
	public boolean supports(Class<? extends Object> authentication) {
		return true;
	}

	public void setPlayerRole(String playerRole) {
		this.playerRole = playerRole;
	}

	public String getPlayerRole() {
		return this.playerRole;
	}
}
